package com.rc.saas.tenant.controller.transfer;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.github.pagehelper.PageInfo;
import com.rc.saas.tenant.base.WebPageInfo;
import com.rc.saas.tenant.common.component.UidGenerator;
import com.rc.saas.tenant.common.constant.ShiroConstants;
import com.rc.saas.tenant.common.sms.AliyunSmsTemplateEnum;
import com.rc.saas.tenant.common.sms.AliyunSmsUtil;
import com.rc.saas.tenant.common.utils.BeanUtil;
import com.rc.saas.tenant.common.utils.StringUtil;
import com.rc.saas.tenant.common.vo.TResponse;
import com.rc.saas.tenant.mapper.transfer.TransferWaysMapper;
import com.rc.saas.tenant.model.member.MemberAccount;
import com.rc.saas.tenant.model.member.MemberInfo;
import com.rc.saas.tenant.model.pay.TenantPayment;
import com.rc.saas.tenant.model.pay.TenantPaymentExample;
import com.rc.saas.tenant.model.tenant.Tenant;
import com.rc.saas.tenant.model.tenant.TenantSetting;
import com.rc.saas.tenant.model.tenant.TenantUser;
import com.rc.saas.tenant.model.tenant.TenantUserExample;
import com.rc.saas.tenant.model.transfer.MemberRefundApply;
import com.rc.saas.tenant.model.transfer.TenantTransfer;
import com.rc.saas.tenant.model.transfer.TransferOrder;
import com.rc.saas.tenant.model.transfer.TransferWays;
import com.rc.saas.tenant.service.member.MemberAccountService;
import com.rc.saas.tenant.service.member.MemberInfoService;
import com.rc.saas.tenant.service.order.OrderInfoService;
import com.rc.saas.tenant.service.pay.TenantPaymentService;
import com.rc.saas.tenant.service.sms.TenantSmsService;
import com.rc.saas.tenant.service.tenant.TenantService;
import com.rc.saas.tenant.service.tenant.TenantSettingService;
import com.rc.saas.tenant.service.tenant.TenantUserService;
import com.rc.saas.tenant.service.transfer.MemberRefundApplyService;
import com.rc.saas.tenant.service.transfer.TenantTransferService;
import com.rc.saas.tenant.service.transfer.TransferOrderService;
import com.rc.saas.tenant.service.weixin.WxPayWalletService;
import com.rc.saas.tenant.shiro.ShiroUtils;
import com.rc.saas.tenant.transfers.weixin.WxTransPayWalletVo;
import com.rc.saas.tenant.util.ExportUtils;
import com.rc.saas.tenant.vo.member.MemberResultVo;
import com.rc.saas.tenant.vo.transfer.MemberRefundApplyExportVo;
import com.rc.saas.tenant.vo.transfer.MemberRefundApplySearch;
import com.rc.saas.tenant.vo.transfer.MemberRefundApplyVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.constraints.NotBlank;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;

/**
 * @author frog
 * @date 2021/8/21
 */
@Validated
@Controller
@RequestMapping("/memberRefundApply")
public class MemberRefundApplyController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MemberRefundApplyService memberRefundApplyService;

    @Autowired
    private WxPayWalletService wxPayWalletService;

    @Autowired
    private TenantService tenantService;

    @Autowired
    private MemberInfoService memberInfoService;

    @Autowired
    private MemberAccountService memberAccountService;

    @Autowired
    private TransferOrderService transferOrderService;

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private TenantTransferService tenantTransferService;

    @Autowired
    private UidGenerator uidGenerator;

    @Autowired
    private TenantSmsService tenantSmsService;

    @Autowired
    private TransferWaysMapper transferWaysMapper;

    @Autowired
    private TenantSettingService tenantSettingService;

    @Autowired
    private TenantPaymentService tenantPaymentService;

    @Autowired
    private TenantUserService tenantUserService;

    /**
     * 跳转余额提现审核页面
     *
     * @return
     */
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(Model model) {
        /*TenantUser user = ShiroUtils.getSessionUser();
        TenantUserExample example = new TenantUserExample();
        example.createCriteria().andTenantCodeEqualTo(user.getTenantCode()).andUserTypeEqualTo("0").andStatusEqualTo("0");
        TenantUser adminUser = tenantUserService.selectByExample(example).stream().findFirst().orElseGet(() -> null);

        TenantTransfer tenantTransfer = tenantTransferService.selectByPrimaryKey(1l);
        if (tenantTransfer == null) {
            model.addAttribute("transferType", "0");
            model.addAttribute("isVerification", tenantTransfer.getIsVerification());
        } else {
            model.addAttribute("transferType", tenantTransfer.getTransferType());
            model.addAttribute("isVerification", tenantTransfer.getIsVerification());
        }
        model.addAttribute("mobile", adminUser.getMobile());*/
        return "/templates/transfer/memberRefundApply";
    }

    /**
     * 返回余额提现审核列表数据
     *
     * @return
     */
    @RequestMapping(value = "/listPageMemberRefundApply", method = RequestMethod.GET)
    @ResponseBody
    public WebPageInfo listPageMemberRefundApply(MemberRefundApplySearch memberRefundApplySearch) {
        PageInfo<MemberRefundApplyVo> pageInfo = memberRefundApplyService.listPageMemberRefundApply(memberRefundApplySearch);
        WebPageInfo webPageInfo = new WebPageInfo(pageInfo.getList(), Long.valueOf(pageInfo.getTotal()).intValue());
        return webPageInfo;
    }

    /**
     * 保存审核
     *
     * @param memberRefundApplyId
     * @return
     */

    @RequestMapping(value = "/updateStatus", method = RequestMethod.POST)
    @ResponseBody
    public TResponse updateStatus(Long memberRefundApplyId, String status, String remark) {
        TenantUser user = ShiroUtils.getSessionUser();
        Date date = new Date();
        MemberRefundApply info = memberRefundApplyService.selectByPrimaryKey(memberRefundApplyId);
        if (info == null) {
            return TResponse.FAIL("请求错误");
        }

        if ("5".equals(status)){
            info.setLastUpdatedBy(user.getLoginName());
            info.setLastUpdatedTime(date);
            info.setAuditingTime(date);
            info.setStatus(status);
            info.setRemark(remark);
            memberRefundApplyService.updateByPrimaryKey(info);
        }

        //瑞晨支付宝转账
        TResponse tResponse = memberRefundApplyService.updateByAliTransfer(user, memberRefundApplyId, status, remark);

        return tResponse;
    }

    /**
     * 获取手机短信验证码
     *
     * @param session
     * @return
     */
    @RequestMapping(value = "/getMemberRefundAuthCode", method = RequestMethod.POST)
    @ResponseBody
    public TResponse getMemberRefundAuthCode(HttpSession session) {
        try {
            TenantUser user = ShiroUtils.getSessionUser();
            TenantUserExample example = new TenantUserExample();
            example.createCriteria().andTenantCodeEqualTo(user.getTenantCode()).andUserTypeEqualTo("0").andStatusEqualTo("0");
            TenantUser adminUser = tenantUserService.selectByExample(example).stream().findFirst().orElseGet(() -> null);

            Tenant tenant = tenantService.selectByTenantCode(user.getTenantCode());
            //验证码
            String smscode = uidGenerator.genSmsAuthCode();

            SendSmsResponse sendResult = AliyunSmsUtil.sendSms(adminUser.getMobile(), smscode, AliyunSmsTemplateEnum.MEMBER_REFUND2, tenant.getSmsSign());

            if (sendResult == null) {
                logger.error("短信系统异常");
                return TResponse.FAIL("短信系统异常");
            }

            if ("OK".equals(sendResult.getCode())) {
                // 更新sms表
                tenantSmsService.updateTenantSmsByTenantCode(tenant.getTenantCode(), adminUser.getMobile(), "0", "tenant,getTicketAuthCode:获取验证码 ,进行会员退款功能:" + user.getMobile(), "获取验证码 ,进行会员退款功能");
            } else {
                logger.error("短信系统异常:" + sendResult.getMessage());
            }

            //将登录验证码保存到会话中
            String sessionAttr = ShiroConstants.SESSION_MEMBER_RREFUND_KEY + adminUser.getMobile();
            String sessionAuthCode = smscode + System.currentTimeMillis();
            session.setAttribute(sessionAttr, sessionAuthCode);

            logger.error("获取手机短信验证码 mobile:{},sessionAttr:{},sessionAuthCode:{}", adminUser.getMobile(), sessionAttr, sessionAuthCode);

            return TResponse.SUCCESS("验证码已发送");
        } catch (Exception e) {
            logger.error("获取会员退款验证码失败", e);
            return TResponse.FAIL("操作失败");
        }


    }


    /**
     * 更改审核记录状态
     *
     * @return
     */
    @RequestMapping(value = "/updateMemberRefundApplyStatus", method = RequestMethod.POST)
    @ResponseBody
    public TResponse updateMemberRefundApplyStuts(HttpSession session, HttpServletRequest request, Long refundApplyId, String status, String remark, String authCode) {
        try {
            TenantUser user = ShiroUtils.getSessionUser();
            TenantUserExample example = new TenantUserExample();
            example.createCriteria().andTenantCodeEqualTo(user.getTenantCode()).andUserTypeEqualTo("0").andStatusEqualTo("0");
            TenantUser adminUser = tenantUserService.selectByExample(example).stream().findFirst().orElseGet(() -> null);

            //转账方式 0人工转帐 1系统自动转帐 默认0
            TenantTransfer tenantTransfer = tenantTransferService.selectByPrimaryKey(1l);

            if ("0".equals(tenantTransfer.getIsVerification()) && "1".equals(status)) {
                String sessionAttr = ShiroConstants.SESSION_MEMBER_RREFUND_KEY + adminUser.getMobile();

                String sessionAuthCode = (String) session.getAttribute(sessionAttr);

                if (StringUtils.isBlank(sessionAuthCode)) {
                    return TResponse.FAIL("未申请验证码");
                }

                if (!authCode.equals(sessionAuthCode.substring(0, 6))) {
                    return TResponse.FAIL("验证码错误");
                }

                session.removeAttribute(sessionAttr);
            }

            MemberRefundApply memberRefundApply = memberRefundApplyService.selectByPrimaryKey(refundApplyId);

            Tenant tenant = tenantService.selectByPrimaryKey(user.getTenantCode());

            if (tenant == null) {
                return TResponse.FAIL("找不到指定的运营商");
            }

            Date date = new Date();
            //审核状态 0未审核，1审核通过，2审核不通过 默认0
            //审核状态 0未审核，1审核通过，2审核不通过 3提款中 4已到账 默认0
            if ("2".equals(status)) {
                if (StringUtil.isBlank(remark)) {
                    return TResponse.FAIL("请填写备注");
                }
                memberRefundApply.setStatus("2");
                memberRefundApply.setLastUpdatedTime(date);
                memberRefundApply.setRemark(remark);
                memberRefundApplyService.updateByPrimaryKeySelective(memberRefundApply);
                return TResponse.SUCCESS();
            }

            MemberInfo memberInfo = memberInfoService.selectByPrimaryKey(memberRefundApply.getMemberId());

            if ("1".equals(memberInfo.getStatus())) {
                return TResponse.FAIL("会员已被冻结");
            }

            MemberAccount memberAccount = memberAccountService.selectByPrimaryKey(memberInfo.getMemberId());

            if (memberRefundApply.getRefundAmount().compareTo(memberAccount.getAccount()) > 0) {
                return TResponse.FAIL("会员余额不足以退款");
            }

            long countTransfer = transferOrderService.countFailTransferOrderByMember(memberInfo.getMemberId());
            if (countTransfer > 0) {
                return TResponse.FAIL("会员还有【" + countTransfer + "】笔未付款成功的订单,请稍后再试");
            }

            long countCharging = orderInfoService.countOrderIsCharging(memberInfo.getMemberId());

            if (countCharging > 0) {
                return TResponse.FAIL("会员还有正在充电的订单,请稍后再试");
            }


            if (tenantTransfer == null) {
                //默认为手动
                tenantTransfer = new TenantTransfer();
                tenantTransfer.setTransferType("0");
            }

            if ("1".equals(status)) {
                if ("1".equals(tenantTransfer.getTransferType())) {
                    //发起付款
                    WxTransPayWalletVo transPayWalletVo = new WxTransPayWalletVo();

                    TenantSetting tenantSetting = new TenantSetting();

                    if ("1".equals(memberRefundApply.getRefundSource())) {
                        TenantPaymentExample tenantPaymentExample = new TenantPaymentExample();
                        tenantPaymentExample.createCriteria().andTenantCodeEqualTo(tenant.getTenantCode()).andPaymentTypeEqualTo("WXPAY");
                        List<TenantPayment> tenantPayments = tenantPaymentService.selectByExample(tenantPaymentExample);

                        if (CollectionUtils.isEmpty(tenantPayments) || StringUtil.isBlank(tenantPayments.get(0).getWxTransferCertPath())) {
                            return TResponse.FAIL("找不到商户证书文件");
                        }

                        TransferWays transferWays = transferWaysMapper.selectByPrimaryKey(memberRefundApply.getMemberId());
                        if (transferWays == null) {
                            return TResponse.FAIL("此用户没有绑定信息");
                        }

                        //设置APP退款信息,路径
                        tenantSetting.setWxTransferCertPath(tenantPayments.get(0).getWxTransferCertPath());

                        tenant.setWechatAppid(tenantPayments.get(0).getAppid());
                        tenant.setWechatPayMchid(tenantPayments.get(0).getMchid());
                        tenant.setWechatPaySecret(tenantPayments.get(0).getPrivateKey());

                        memberInfo.setWechatOpenid(transferWays.getWxOpenid());
                    } else {

                        tenantSetting = tenantSettingService.selectByPrimaryKey(tenant.getTenantCode());
                        if (tenantSetting == null || StringUtils.isBlank(tenantSetting.getWxTransferCertPath())) {
                            return TResponse.FAIL("找不到商户证书文件");
                        }

                        if (StringUtil.isBlank(memberInfo.getWechatOpenid())) {
                            return TResponse.FAIL("此用户没有绑定微信");
                        }

                    }

                    transPayWalletVo.setRealName(memberRefundApply.getMemberRealName());

                    transPayWalletVo.setAmount(memberRefundApply.getRefundAmount());
                    transPayWalletVo.setMobile(memberInfo.getMobile());

                    //申请单ID
                    if (memberRefundApply != null) {
                        transPayWalletVo.setRefundApplyId(memberRefundApply.getRefundApplyId());
                    }
                    TResponse tResponse = wxPayWalletService.transPayWallet(request, tenant, memberInfo, transPayWalletVo, tenantSetting);
                    return tResponse;
                } else if ("0".equals(tenantTransfer.getTransferType())) {
                    memberRefundApply.setStatus("3");
                    memberRefundApply.setLastUpdatedTime(date);
                    memberRefundApplyService.updateByPrimaryKeySelective(memberRefundApply);
                    return TResponse.SUCCESS();
                } else {
                    return TResponse.FAIL("请设置正确的提现方式");
                }
            }

            TResponse tResponse = memberRefundApplyService.updateMemberRefundApplyStatus(memberRefundApply, memberAccount, status, memberInfo, tenant);

            return tResponse;
        } catch (Exception e) {
            logger.error("更改审核记录状态失败", e);
            return TResponse.FAIL("操作失败");
        }
    }


    /**
     * 批量更改审核记录状态
     *
     * @return
     */
    @RequestMapping(value = "/batchUpdateMemberRefundApplyStuts", method = RequestMethod.POST)
    @ResponseBody
    public TResponse batchUpdateMemberRefundApplyStuts(HttpSession session, HttpServletRequest request, String refundApplyIdsJson, String status, String remark, String authCode) {
        try {
            TenantUser user = ShiroUtils.getSessionUser();
            TenantUserExample example = new TenantUserExample();
            example.createCriteria().andTenantCodeEqualTo(user.getTenantCode()).andUserTypeEqualTo("0").andStatusEqualTo("0");
            TenantUser adminUser = tenantUserService.selectByExample(example).stream().findFirst().orElseGet(() -> null);
            //转账方式 0人工转帐 1系统自动转帐 默认0
            TenantTransfer tenantTransfer = tenantTransferService.selectByPrimaryKey(1l);

            if ("0".equals(tenantTransfer.getIsVerification()) && "1".equals(status)) {
                String sessionAttr = ShiroConstants.SESSION_MEMBER_RREFUND_KEY + adminUser.getMobile();

                String sessionAuthCode = (String) session.getAttribute(sessionAttr);

                if (StringUtils.isBlank(sessionAuthCode)) {
                    return TResponse.FAIL("未申请验证码");
                }

                if (!authCode.equals(sessionAuthCode.substring(0, 6))) {
                    return TResponse.FAIL("验证码错误");
                }

                session.removeAttribute(sessionAttr);
            }

            //审核状态 0未审核，1审核通过，2审核不通过 默认0
            if ("2".equals(status) && StringUtil.isBlank(remark)) {
                return TResponse.FAIL("请填写备注");
            }

            Tenant tenant = tenantService.selectByPrimaryKey(user.getTenantCode());

            if (tenant == null) {
                return TResponse.FAIL("找不到指定的运营商");
            }
            if (refundApplyIdsJson == null) {
                return TResponse.FAIL("入参不能为空");
            }

            //JSONObject jsonObject = JSONObject.parseObject(refundApplyIdsJson);
            Object[] objects = JSONArray.parseArray(refundApplyIdsJson).toArray();

            return memberRefundApplyService.batchUpdateMemberRefundApplyStuts(objects, status, remark, tenantTransfer, request);
        } catch (Exception e) {
            logger.error("更改审核记录状态失败", e);
            return TResponse.FAIL("操作失败");
        }
    }


    /**
     * 跳转新增审核记录页面
     *
     * @return
     */
    @RequestMapping(value = "/addMemberRefundApply", method = RequestMethod.GET)
    public String addMemberRefundApply(Model model) {
        TenantUser user = ShiroUtils.getSessionUser();
        TenantTransfer tenantTransfer = tenantTransferService.selectByPrimaryKey(1l);
        model.addAttribute("tenantTransfer", tenantTransfer);
        return "/templates/transfer/addMemberRefundApply";
    }


    /**
     * 通过手机号查询用户信息
     *
     * @return
     */
    @RequestMapping(value = "/selectMemberAndAccountByMobile", method = RequestMethod.GET)
    @ResponseBody
    public TResponse selectMemberAndAccountByMobile(@NotBlank(message = "请输入正确的手机号") String mobile) {
        TenantUser tenantUser = ShiroUtils.getSessionUser();
        MemberResultVo memberInfo = memberInfoService.selectMemberAndAccountByMobile(tenantUser.getTenantCode(), mobile);
        if (memberInfo == null) {
            return TResponse.FAIL("不存在此用户");
        }
        return TResponse.SUCCESS_DATA(memberInfo);
    }


    /**
     * 保存审核记录
     *
     * @return
     */
    @RequestMapping(value = "/saveMemberRefundApply", method = RequestMethod.POST)
    @ResponseBody
    public TResponse saveOrUpdateBanner(MemberRefundApply memberRefundApply) {
        if (memberRefundApply.getMemberId() == null) {
            return TResponse.FAIL("请先查询会员");
        }
        if (!BeanUtil.isValid(memberRefundApply.getRefundAmount())) {
            return TResponse.FAIL("请输入正确的提现金额");
        }
        TenantUser user = ShiroUtils.getSessionUser();
        try {
            MemberAccount memberAccount = memberAccountService.selectByPrimaryKey(memberRefundApply.getMemberId());
            if (memberAccount.getAccount().compareTo(memberRefundApply.getRefundAmount()) < 0) {
                return TResponse.FAIL("剩余余额不足");
            }

            memberRefundApply.setTenantCode(user.getTenantCode());
            //memberRefundApply.setRefundSource("3");
            memberRefundApplyService.insertSelective(memberRefundApply);
            return TResponse.SUCCESS();
        } catch (
                Exception e) {
            logger.error("保存审核记录失败", e);
            return TResponse.FAIL("操作失败");
        }
    }


    /**
     * 跳转审核记录详情页面
     *
     * @return
     */
    @RequestMapping(value = "/getMemberRefundApplyDetail/{refundApplyId}", method = RequestMethod.GET)
    public String getMemberRefundApplyDetail(@PathVariable("refundApplyId") Long refundApplyId, Model model) {
        MemberRefundApply memberRefundApply = memberRefundApplyService.selectByPrimaryKey(refundApplyId);
        if (memberRefundApply.getMemberId() != null) {
            MemberInfo memberInfo = memberInfoService.selectByPrimaryKey(memberRefundApply.getMemberId());
            model.addAttribute("memberInfo", memberInfo);
        }
        TransferOrder transferOrder = transferOrderService.selectByRefundApplyId(memberRefundApply.getRefundApplyId());
        model.addAttribute("memberRefundApply", memberRefundApply);
        model.addAttribute("transferOrder", transferOrder);
        return "/templates/transfer/memberRefundApplyDetail";
    }


    /**
     * 导出余额提现申请列表
     */
    @ResponseBody
    @RequestMapping("/exportMemberRefundApply")
    public TResponse exportMemberRefundApply(MemberRefundApplySearch memberRefundApplySearch, HttpServletResponse response) {
        response.setHeader("Set-Cookie", "fileDownload=true; path=/");
        ExportUtils.setDefaultPaging(memberRefundApplySearch);
        if (memberRefundApplySearch.getCount() == 0 || memberRefundApplySearch.getCount() == null) {
            memberRefundApplySearch.setCount(memberRefundApplySearch.getLimit());
        }

        //导出拼接开始条数
        memberRefundApplySearch.setOffset(memberRefundApplySearch.getLimit() * (memberRefundApplySearch.getOffset() - 1));
        List<MemberRefundApplyExportVo> list = memberRefundApplyService.exportMemberRefundApply(memberRefundApplySearch);

        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("余额提现列表", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), MemberRefundApplyExportVo.class).sheet("余额提现列表").doWrite(list);
            return TResponse.SUCCESS();
        } catch (Exception e) {
            logger.error("导出余额提现申请失败", e.getMessage());
            return TResponse.FAIL(e.getMessage());
        }
    }

    public static void main(String[] args) {
        String str = "{'list':[123,456,789]}";
        JSONObject jsonObject = JSONObject.parseObject(str);
        JSONArray modifyArray = JSONArray.parseArray(jsonObject.getString("list"));
        for (Object o : modifyArray) {
            System.out.println(o);
        }

    }
}
